package com.example.zqh.utils.es;

import com.example.zqh.pojo.Food;
import com.example.zqh.pojo.params.FoodPlus;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.suggest.SuggestBuilder;
import org.elasticsearch.search.suggest.SuggestBuilders;
import org.elasticsearch.search.suggest.completion.CompletionSuggestion;
import org.springframework.beans.factory.annotation.Autowired;
import static com.example.zqh.pojo.contants.ElasticSearchFood.MAPPING_FOOD;
import com.alibaba.fastjson.JSON;
import org.springframework.context.annotation.Configuration;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author: zqh
 * @Date: 2022-09-14-18:42
 * @Description: food表上传es$
 */
@Configuration
public class EsFoodUtils {
    
    private static final String INDEX_LIBRARY = "foods";

    private static final String AUTOCOMPLETE_FIELD_NAME = "suggestion";

    @Autowired
    private RestHighLevelClient client;
    
    
    /**
      * @Author: zqh
      * @Date: 
      * @Description: 创建food表的es数据库
    */
    public boolean CreateIndex()throws IOException{
        //1创建request对象
        CreateIndexRequest request = new CreateIndexRequest(INDEX_LIBRARY);
        //2准备请求的参数
        request.source(MAPPING_FOOD, XContentType.JSON);
        //3发送请求
        client.indices().create(request, RequestOptions.DEFAULT);
        return true;
    }

    /**
      * @Author: zqh
      * @Date:
      * @Description: 删除food表的es数据库
    */
    public boolean DeleteIndex() throws IOException {
        DeleteIndexRequest request = new DeleteIndexRequest(INDEX_LIBRARY);
        client.indices().delete(request, RequestOptions.DEFAULT);
        return true;
    }


    /**
     * @Author: zqh
     * @Date:
     * @Description: 判断es数据库是否存在
     */
    public boolean GetIndex()throws IOException {
        GetIndexRequest request = new GetIndexRequest(INDEX_LIBRARY);
        Boolean expected = client.indices().exists(request, RequestOptions.DEFAULT);
        return expected;
    }

    /**
      * @Author: zqh
      * @Date:
      * @Description: 上传一条数据库到es
    */
    public boolean addOne(Food food) throws IOException {
        FoodPlus foodPlus = new FoodPlus(food);
        IndexRequest id = new IndexRequest(INDEX_LIBRARY).id(foodPlus.getId().toString());
        id.source(JSON.toJSONString(foodPlus),XContentType.JSON);
        IndexResponse index = client.index(id, RequestOptions.DEFAULT);
        int successful = index.getShardInfo().getSuccessful();
        return successful == 1 ? true : false;
    }

    /**
      * @Author: zqh
      * @Date:
      * @Description: 上传多条数据
    */
    public boolean addAll(List<Food> foods) throws IOException {
        BulkRequest request = new BulkRequest();
        for (Food food : foods) {
            FoodPlus foodPlus = new FoodPlus(food);
            request.add(new IndexRequest(INDEX_LIBRARY).id(foodPlus.getId().toString()).source(JSON.toJSONString(foodPlus),XContentType.JSON));
        }
        client.bulk(request,RequestOptions.DEFAULT);
        return true;

    }

    /**
      * @Author: zqh
      * @Date:
      * @Description: 修改某条数据
    */
    public boolean updateOne(Food food)throws IOException {
        FoodPlus foodPlus = new FoodPlus(food);
        IndexRequest id = new IndexRequest(INDEX_LIBRARY).id(foodPlus.getId().toString());
        id.source(JSON.toJSONString(foodPlus),XContentType.JSON);
        IndexResponse index = client.index(id, RequestOptions.DEFAULT);
        int successful = index.getShardInfo().getSuccessful();
        return successful == 1 ? true : false;
    }

    /**
     * @Author: zqh
     * @Date:
     * @Description: 删除某个
     */
    public boolean deleteOne(int id) throws IOException {
        DeleteRequest deleteRequest = new DeleteRequest(INDEX_LIBRARY, String.valueOf(id));
        DeleteResponse delete = client.delete(deleteRequest, RequestOptions.DEFAULT);
        int successful = delete.getShardInfo().getSuccessful();
        return successful == 1 ? true : false;
    }

    /**
     * @Author: zqh
     * @Date:
     * @Description: 自动补全，用于别人输入查询时自动补全
     */
    public List<String> getAutocompletionList(String content) throws IOException {
        SearchRequest request = new SearchRequest(INDEX_LIBRARY);
        request.source().suggest(new SuggestBuilder().addSuggestion(
                "suggestions",
                SuggestBuilders.completionSuggestion("suggestion")
                        .prefix(content)
                        .skipDuplicates(true)
                        .size(5)
        ));
        SearchResponse search = client.search(request, RequestOptions.DEFAULT);
        CompletionSuggestion getAutocompletionList = search.getSuggest().getSuggestion("suggestions");
        List<String> strings = new ArrayList<>();
        List<CompletionSuggestion.Entry.Option> options1 = getAutocompletionList.getOptions();
        for (CompletionSuggestion.Entry.Option option : options1) {
            String s = option.getText().toString();
            strings.add(s);
        }
        return strings;
    }

    /**
     * @Author: zqh
     * @Date:
     * @Description: 通过suggestion查询
     */
    public List<Food> selectBySuggest(String keyword) throws IOException{
        SearchRequest request = new SearchRequest(INDEX_LIBRARY);
        request.source().query(QueryBuilders.matchQuery(AUTOCOMPLETE_FIELD_NAME,keyword));
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        SearchHits hits = response.getHits();
        SearchHit[] searchHits = hits.getHits();
        ArrayList<Food> songs = new ArrayList<>();
        for (SearchHit hit : hits) {
            String json = hit.getSourceAsString();
            Food song = JSON.parseObject(json, Food.class);
            songs.add(song);
        }
        return songs;
    }

    /**
      * @Author: zqh
      * @Date:
      * @Description: 分页查询食物
    */
    public List<Food> selectAllList(Integer page,Integer size)throws IOException {
        SearchRequest searchRequest = new SearchRequest(INDEX_LIBRARY);
        searchRequest.source().query(QueryBuilders.matchAllQuery());
        searchRequest.source().from(page).size(size);
        SearchResponse search = client.search(searchRequest, RequestOptions.DEFAULT);
        return getFoodList(search);

    }

    /**
      * @Author: zqh
      * @Date:
      * @Description: 通过typeId字段分页查询食物
    */
    public List<Food> selectListByTypeId(Integer typeId,Integer page,Integer size) throws IOException {
        SearchRequest searchRequest = new SearchRequest(INDEX_LIBRARY);
        searchRequest.source().query(QueryBuilders.matchQuery("foodType",typeId));
        searchRequest.source().from(page).size(size);
        SearchResponse search = client.search(searchRequest, RequestOptions.DEFAULT);
        return getFoodList(search);
    }

    /**
      * @Author: zqh
      * @Date:
      * @Description: 通过店铺id分页查询food
    */
    public List<Food> selectListByShopId(Integer shopId,Integer page,Integer size) throws IOException {
        SearchRequest searchRequest = new SearchRequest(INDEX_LIBRARY);
        searchRequest.source().query(QueryBuilders.matchQuery("shopId",shopId));
        searchRequest.source().from(page).size(size);
        SearchResponse search = client.search(searchRequest, RequestOptions.DEFAULT);
        return getFoodList(search);
    }











    private List<Food> getFoodList(SearchResponse search){
        ArrayList<Food> foods = new ArrayList<>();
        SearchHit[] hits = search.getHits().getHits();
        for (SearchHit hit : hits) {
            String sourceAsString = hit.getSourceAsString();
            Food food = JSON.parseObject(sourceAsString, Food.class);
            foods.add(food);
        }
        return foods;
    }
}
